#include <iostream>
#include <string>
#include <vector>
#include <cstring>
#include <cstdio>
#include <unistd.h>
#include <pthread.h>
#include "Thread.hpp"
#include "Mutex.hpp"
#include <memory>

// string changeId(const pthread_t &thread_id)
// {
//     char tid[128];
//     snprintf(tid, sizeof(tid), "0x%x", thread_id);
//     return tid;
// }

// void *start_routine(void *args)
// {
//     string threadname = static_cast<const char*>(args);
//     int cnt = 5;
//     while(cnt--)
//     {
//         cout << threadname << " running ..." << changeId(pthread_self()) << endl;
//         sleep(1);
//     }
//     return nullptr;
// }

int tickets = 1000;

// 使用全局锁
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

class ThreadData
{
public:
    ThreadData(const std::string &threadname, pthread_mutex_t *mutex_p) : threadname_(threadname), mutex_p_(mutex_p)
    {
    }
    ~ThreadData()
    {
    }

public:
    std::string threadname_;
    pthread_mutex_t *mutex_p_;
};

void *getTicket(void *args)
{
    // std::string useranme = static_cast<const char*>(args);
    ThreadData *td = static_cast<ThreadData *>(args);
    while (true)
    {

        // pthread_mutex_lock(td->mutex_p_);

        // Mutex mutex(td->mutex_p_);
        // mutex.lock();

        {
            LockGuard lockguard(&lock); // RAII风格的加锁!
            if (tickets > 0)
            {
                usleep(1000);

                std::cout << td->threadname_ << " 正在进行抢票: " << tickets << std::endl;

                tickets--;

                // pthread_mutex_unlock(td->mutex_p_);

                // mutex.unlock();
            }
            else
            {
                // pthread_mutex_unlock(td->mutex_p_);

                // mutex.unlock();

                break;
            }
        }
        usleep(1); // 只要能够让OS能够发生线程切换就行
        // usleep(1000);
    }
    delete td;
    return nullptr;
}

void *thread_run(void *args)
{
    std::string work_type = static_cast<const char *>(args);
    while (true)
    {
        std::cout << "我是一个新线程, 我正在做: " << work_type << std::endl;
        sleep(1);
    }
}

int main()
{
#define NUM 4

    // pthread_mutex_t lock;
    // pthread_mutex_init(&lock, nullptr);

    std::vector<pthread_t> tids(NUM);

    for (int i = 0; i < NUM; ++i)
    {
        char buffer[64];
        snprintf(buffer, sizeof buffer, "thread %d", i + 1);
        ThreadData *td = new ThreadData(buffer, &lock);
        pthread_create(&tids[i], nullptr, getTicket, td);
    }

    for (int i = 0; i < NUM; ++i)
    {
        pthread_join(tids[i], nullptr);
    }

    // 也可以不用局部锁, 改用全局锁
    // pthread_mutex_destroy(&lock);

    // std::unique_ptr<Thread> thread1(new Thread(thread_run, (void*)"hellothread", 1));
    // std::unique_ptr<Thread> thread2(new Thread(thread_run, (void*)"countthread", 2));
    // std::unique_ptr<Thread> thread3(new Thread(thread_run, (void*)"logthread", 3));
    // // thread1->start();
    // // thread2->start();
    // // thread3->start();
    // thread1->join();
    // thread2->join();
    // thread3->join();
    // pthread_t tid;
    // pthread_create(&tid, nullptr, start_routine, (void*)"thread one");

    // pthread_detach(pthread_self());

    // string main_id = changeId(pthread_self());
    // cout << "main thread running ... new thread id: " << changeId(tid) << " main thread id: " << main_id << endl;

    // sleep(5);
    // //int n = pthread_join(tid, nullptr);
    // //if(n < 0) cerr << "errno: " << errno << strerror(errno) << endl;
    // //cout << "result: " << n << strerror(n) << endl;
    return 0;
}